package org.springframework.boot;

import org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor;
import org.springframework.boot.context.event.EventPublishingRunListener;
import org.springframework.boot.env.EnvironmentPostProcessorApplicationListener;
import org.springframework.boot.env.RandomValuePropertySourceEnvironmentPostProcessor;
import org.springframework.boot.logging.DeferredLog;
import org.springframework.boot.logging.DeferredLogs;
import org.springframework.core.env.PropertySource;

/**
 * @author shiminghui
 * @date 2025/5/7 21:14
 * @description: TODO
 */
public class Step5 {
    public static void main(String[] args) {
//        test1();
        // 当然了,这些后处理器不是代码里写死的,而是写在配置文件里面的
        SpringApplication application = new SpringApplication();

        /*List<String> list =
                SpringFactoriesLoader.loadFactoryNames(EnvironmentPostProcessor.class, Step5.class.getClassLoader());
        for (String s : list) {
            System.out.println(s);
        }*/
        // 那么是谁读取的这些后处理器呢?
        // 其实是一个监听器来干的这件事,他会找到所有需要加载的后处理器,然后调用后处理器的postProcessEnvironment方法

        // 模拟这个过程
        // 首先是事件发布器(这个发布器也是配置文件里的,是动态加载的)
        EventPublishingRunListener publisher = new EventPublishingRunListener(application, args);

        // 其次,添加监听器(这个过程是创建springApplication时执行的,也是读取配置文件)
        application.addListeners(new EnvironmentPostProcessorApplicationListener());
        ApplicationEnvironment environment = new ApplicationEnvironment();

        System.out.println("增强前");
        for (PropertySource<?> ps : environment.getPropertySources()) {
            System.out.println(ps.getName());
        }

        // 第5步是发布事件, 这个事件会触发所有的监听器, 监听器会调用后处理器的postProcessEnvironment方法
        publisher.environmentPrepared(new DefaultBootstrapContext(), environment);
        // 这里的environment被当成参数传递过去,进行增强

        // 打印测试一下
        System.out.println("增强后");
        for (PropertySource<?> ps : environment.getPropertySources()) {
            System.out.println(ps.getName());
        }


    }

    private static void test1() {
        SpringApplication springApplication = new SpringApplication();
        ApplicationEnvironment env = new ApplicationEnvironment();
        // 第5步是添加环境的后处理器, 这个后处理器会去加载配置文件, 并且把配置文件加载到环境变量中,
        // 咱们的application.properties就是这时候加载的配置文件

        // 增强前
        System.out.println("增强前");
        for (PropertySource<?> ps : env.getPropertySources()) {
            System.out.println(ps.getName());
        }

        // 这个后处理器会将application.properties和application.yml加载到环境变量中
        ConfigDataEnvironmentPostProcessor postProcessor1 = new ConfigDataEnvironmentPostProcessor(new DeferredLogs(), new DefaultBootstrapContext());
        postProcessor1.postProcessEnvironment(env, springApplication);
        // 增强后
        System.out.println("增强后");
        for (PropertySource<?> ps : env.getPropertySources()) {
            System.out.println(ps.getName());
        }

        // 一个有意思的后处理器
        RandomValuePropertySourceEnvironmentPostProcessor postProcessor2 = new RandomValuePropertySourceEnvironmentPostProcessor(new DeferredLog());
        postProcessor2.postProcessEnvironment(env, springApplication);
        System.out.println("增强后2");
        for (PropertySource<?> ps : env.getPropertySources()) {
            System.out.println(ps.getName());
        }

        // 尝试获取属性值
        System.out.println("---------------------------------");
        System.out.println(env.getProperty("test.value"));

        System.out.println(env.getProperty("random.int"));
        System.out.println(env.getProperty("random.int"));
        System.out.println(env.getProperty("random.int"));
        System.out.println(env.getProperty("random.int"));

        System.out.println(env.getProperty("random.uuid"));
        System.out.println(env.getProperty("random.uuid"));
        System.out.println(env.getProperty("random.uuid"));
    }
}
